package com.nyt.org.common.utils.xml;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.mapper.MapperWrapper;
import com.thoughtworks.xstream.security.AnyTypePermission;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class XmlUtils {

    private static Logger log = LoggerFactory.getLogger(XmlUtils.class);

    private static String XML_TAG = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
    private static final String OBJ = "obj";

    private static final XStream xStream = XStreamFactory.getXStream();

    /**
     * 对象转xml
     *
     * @param obj 对象
     * @return
     */
    public static String toXml(Object obj) {
        xStream.processAnnotations(obj.getClass());
        //如果生成的是Objec不显示class属性
        xStream.aliasSystemAttribute(null, "class");
        return XML_TAG + xStream.toXML(obj);
    }
    /**
     * 定制化需求 特殊处理XStream对象
     * @return
     */
    private static XStream getInstance() {
        XStream xStream = new XStream(new DomDriver("UTF-8")) {
            /**
             * 忽略xml中多余字段
             */
            @Override
            protected MapperWrapper wrapMapper(MapperWrapper next) {
                return new MapperWrapper(next) {
                    @SuppressWarnings("rawtypes")
                    @Override
                    public boolean shouldSerializeMember(Class definedIn, String fieldName) {
                        if (definedIn == Object.class) {
                            return false;
                        }
                        return super.shouldSerializeMember(definedIn, fieldName);
                    }
                };
            }
        };

        // 设置默认的安全校验
        XStream.setupDefaultSecurity(xStream);
        // 使用本地的类加载器
        xStream.setClassLoader(XmlUtils.class.getClassLoader());
        // 允许所有的类进行转换
        xStream.addPermission(AnyTypePermission.ANY);
        return xStream;
    }

    /**
     * xml 转 bean
     *
     * @param xml
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T xmlToBean(String xml, Class<T> clazz) {
        //log.info("XmlUtils工具replace之后的报文为：\n"+xml);
        XStream instance = getInstance();
        instance.processAnnotations(clazz);
        instance.autodetectAnnotations(true);
        //修改 xml -> s
        T obj = (T) instance.fromXML(xml.trim());
        return obj;
    }
}
